package net.wangds.jpa.repository;

import net.wangds.log.helper.LogHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

public final class RepositoryUtils {

    public static <T, R extends JpaRepository<T, String>> T saveAndFlush(R repo, T entity){
        Objects.requireNonNull(repo);
        Objects.requireNonNull(entity);
        while(true) {
            try {
                return repo.saveAndFlush(entity);
            }catch (Exception e){
                String msg = e.getLocalizedMessage();
                LogHelper.error(msg);
                if(StringUtils.containsAny(msg.toLowerCase(),"uni", "primary", "constraint", "duplicate")){
                    return entity;
                }
            }
        }
    }

    public static <T, R extends  JpaRepository<T, String>> List<T> saveAndFlushAll(R repo, Iterable<T> it){
        Objects.requireNonNull(repo);
        Objects.requireNonNull(it);
        List<T> res = new ArrayList<>();
        it.forEach(c->res.add(saveAndFlush(repo, c)));
        return res;
    }

    public static <T, R extends JpaRepository<T, String>> List<T> saveAndFlushAllParallelOrder(R repo, Collection<T> collection){
        Objects.requireNonNull(repo);
        Objects.requireNonNull(collection);
        List<T> res = new ArrayList<>();
        collection.parallelStream().forEachOrdered(c->res.add(saveAndFlush(repo,c)));
        return res;
    }

    public static <T, R extends JpaRepository<T, String>> List<T> saveAndFlushAllParallel(R repo, Collection<T> collection){
        Objects.requireNonNull(repo);
        Objects.requireNonNull(collection);
        List<T> res = new ArrayList<>();
        collection.parallelStream().forEach(c->res.add(saveAndFlush(repo,c)));
        return res;
    }

}
